package com.briup.dataset.service.impl;

import com.briup.common.exception.CustomerException;
import com.briup.common.util.ClassifyAndEntityUtil;
import com.briup.common.util.PageResult;
import com.briup.common.web.MessageStatus;
import com.briup.common.web.SecurityUtil;
import com.briup.dataset.constant.DataSetConstant;
import com.briup.dataset.entity.Classify;
import com.briup.dataset.entity.DataSet;
import com.briup.dataset.entity.extend.ClassifyEx;
import com.briup.dataset.entity.extend.DataSetEx;
import com.briup.dataset.mapper.DataSetMapper;
import com.briup.dataset.mapper.extend.ClassifyExtendMapper;
import com.briup.dataset.mapper.extend.DataSetExtendMapper;
import com.briup.dataset.service.IDatasetService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 数据集服务实现类
 */
@Service
public class DatasetServiceImpl implements IDatasetService {
    @Autowired
    private DataSetMapper dataSetMapper;
    @Autowired
    private DataSetExtendMapper dataSetExtendMapper;
    @Autowired
    private ClassifyExtendMapper classifyExtendMapper;

    /*
     * @Description 只插入数据集 数据集下暂时没有分类和数据集
     * @Param [DataSet] 数据集类参数
     * @return void
     **/
    @Transactional
    @Override
    public void insertDataset(DataSet dataSet) throws CustomerException {
        // 判断数据集名称是否存在
        DataSet dFromDb = dataSetExtendMapper.findByName(dataSet.getDatasetName());
        if (dFromDb != null) {
            throw new CustomerException(MessageStatus.DATA_EXISTED);
        }
        try {
            // 1.将数据集实体插入到d_dateset表
            // 1.1 需要补充数据集完整数据 dattasetTime/datasetStatus/datasetRadio(预留字段)
            dataSet.setDatasetTime(new Date());
            dataSet.setDatasetStatus(DataSetConstant.DATASET_STATUS_INIT); // 1:数据集可用 2:数据集不可用 3:正在上传
            // 需要认证SecurityUtil中才会有数据
            dataSet.setUserName(SecurityUtil.getUsername());
            // 1.2 将完整实体插入到数据库
            dataSetMapper.insert(dataSet);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomerException(MessageStatus.SYSTEM_INNER_ERROR);
        }
    }

    /*
     * @Description 条件查询分页结果集拓展 注意,隐藏条件(数据状态!=2,未删除)
     * @Param [datasetType, datasetName, pageNum, pageSize] 数据集类型,数据集名称,当前页,每页显示条数
     * @return 分页结果
     **/
    @Override
    public PageResult<DataSetEx> selectDataSetExListByCon(String datasetType, String datasetName, int pageNum, int pageSize) {
        // 封装查询条件
        Map<String, Object> map = new HashMap<>();
        map.put("datasetType", datasetType);
        map.put("datasetName", datasetName);

        PageHelper.startPage(pageNum, pageSize);
        // 分页并条件查询所有的数据集
        Page<DataSetEx> page = dataSetExtendMapper.selectDataSetExListByCon(map);

        // 遍历分页结果集
        for (DataSetEx dataSetEx : page.getResult()) {
            // 封装数据集扩展类
            fillDataSetEx(dataSetEx);
        }
        return new PageResult<DataSetEx>(page.getTotal(), page.getResult());
    }
    // 查询所有数据集以及拓展(和上面按方法一样,不分页和条件)
    @Override
    public List<DataSetEx> selectDataSetExList() {
        List<DataSetEx> datasetExList = dataSetExtendMapper.selectDataSetExList();
        // 遍历分页结果集
        for (DataSetEx dataSetEx : datasetExList) {
            // 封装数据集扩展类
            fillDataSetEx(dataSetEx);
        }
        return datasetExList;
    }


    /*
     * @Description 根据数据集id查看数据集扩展详情
     * @Param [id] 数据集id
     * @return 数据集扩展实体 分类数,分类下图片数,数据集下所有图片数
     **/
    @Override
    public DataSetEx selectDataSetExById(int id) {
        // 查数据集的基本信息
        DataSetEx dataSetEx = dataSetExtendMapper.selectdataSetEx(id);
        // 填充数据集扩展类
        fillDataSetEx(dataSetEx);
        return dataSetEx;
    }


    /*
     * @Description 删除数据集 事实上只是改变数据的状态 2:不可用
     * @Param [datasetId] 数据集id
     * @return void
     **/
    @Transactional
    @Override
    public void updateDatasetStatus(List<Integer> ids) throws CustomerException {
        for (Integer datasetId : ids) {
            // 查询该数据集信息
            DataSet dataSet = dataSetMapper.selectByPrimaryKey(datasetId);
            if (dataSet == null) {
                throw new CustomerException(MessageStatus.DATA_NONE);
            }
            // 逻辑删除
            dataSet.setDatasetStatus(DataSetConstant.DATASET_STATUS_DELETE);
            dataSetMapper.updateByPrimaryKeySelective(dataSet);
        }
    }

    // 封装填充数据集扩展的方法
    private void fillDataSetEx(DataSetEx dataSetEx) {
        // 封装扩展数据
        List<Map<String, String>> maps = dataSetExtendMapper.selectClassifyAndEntity(dataSetEx.getId());
        // 将<a,b> <a,c>的map集合转换为 <a,[b,c]> 的形式,方便统计分类和实体数量
        Map<String, List<String>> classifyAndEntity = ClassifyAndEntityUtil.toClassifyAndEntity(maps);

        // 封装该数据下所有的分类信息以及对应的分类图片数量(此处构建了classfiyEx扩展类,后面需要使用)
        // 查出基本的分类信息
        List<Classify> classifyList = classifyExtendMapper.selectByDataSetId(dataSetEx.getId());
        // 填充分类扩展类中
        List<ClassifyEx> classifyExList = fillClassifyExList(classifyList, classifyAndEntity);
        // 填充据集下所有图片的数量
        int sum = getEntityNumInDataset(classifyExList, classifyAndEntity);

        // 封装数据集下所有图片数量
        dataSetEx.setEntityNum(sum);
        // 数据扩展类封装分类扩展类
        dataSetEx.setClassifyExList(classifyExList);
        // 封装分类数量
        dataSetEx.setClassifyNum(classifyAndEntity.keySet().size());
    }

    // 封装数据集下所有图片按数量
    private int getEntityNumInDataset(List<ClassifyEx> classifyExList, Map<String, List<String>> classifyAndEntity) {
        int sum = 0;
        // 此处修改了新增分类,数量为1的bug
        for (ClassifyEx classifyEx : classifyExList) {
            sum += classifyAndEntity.get(classifyEx.getClassifyName()).size();
        }
        return sum;
    }

    // 封装数据集下的分类扩展集合
    private List<ClassifyEx> fillClassifyExList(List<Classify> classifyList, Map<String, List<String>> classifyAndEntity) {
        List<ClassifyEx> classifyExList = new ArrayList<>();
        classifyList.forEach(classify -> {
            ClassifyEx classifyEx = new ClassifyEx();
            classifyEx.setId(classify.getId());
            classifyEx.setClassifyName(classify.getClassifyName());
            classifyEx.setClassifyTime(classify.getClassifyTime());
            // 分类扩展类中 每个分类对应的图片数量
            classifyEx.setEntityInClassify(classifyAndEntity.get(classifyEx.getClassifyName()).size());
            classifyExList.add(classifyEx);
        });
        return classifyExList;
    }
}


